#include "../include/sem.h"

/*************************************/
/* 信号灯操作*/
/*************************************/
int init_sem(int semid, int num, int val)
{
	union semun myun;
	myun.val = val;
	if(semctl(semid, num, SETVAL, myun) < 0)
	{
		perror("semctl");
		exit(1);
	}
	return 0;
}

int sem_p(int semid, int num) //申请资源,P操作
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op = -1;
	mybuf.sem_flg = SEM_UNDO; //当进程终止时,信号灯自动撤销 
	if(semop(semid, &mybuf, 1) < 0)
	{
		perror("semop");
		exit(1);
	}

	return 0;
}

int sem_v(int semid, int num) //释放资源V操作
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op = 1;
	mybuf.sem_flg = SEM_UNDO;
	if(semop(semid, &mybuf, 1) < 0)
	{
		perror("semop");
		exit(1);
	}

	return 0;
}

/*************************************************/
/* 主程序端的用到的共享内存初始化以及信号灯初始化*/
/*************************************************/
void init_mem(void)
{
	int shmid;
    if ((key_info = ftok ("./app", 'i')) < 0)
    {
        perror ("ftok info");
        exit (-1);
    }
    if ((shmid = shmget (key_info, N, IPC_CREAT | IPC_EXCL | 0666)) < 0)
    {
        if (errno == EEXIST)
        {
            shmid = shmget (key_info, N, 0666);
            shm_buf = (struct env_info *)shmat (shmid, NULL, 0);

        }
        else
        {
            perror ("shmget");
            exit (-1);
        }

    }
    else
    {
        if ((shm_buf = (struct env_info *)shmat (shmid, NULL, 0)) == (void *)-1)
        {
            perror ("shmat");
            exit (-1);
        }
    }

    bzero (shm_buf, sizeof (struct env_info));
}

void fisrt_init_sem(void)
{
	printf("key_info = %d\n",key_info);
	if ((semid = semget (key_info, 1, IPC_CREAT | IPC_EXCL |0666)) < 0)
	{
		printf("semid = %d\n",semid);
		if (errno == EEXIST)
		{
			semid = semget (key_info, 1, 0666);
            init_sem (semid,0,1);
            printf("sem_init\n");
		}
		else
		{
			perror ("semget");
			exit (-1);
		}
	}
	else
	{
		init_sem (semid,0,1);
		printf("sem_init\n");
	}
}
